package mylib.dir;


/**
 * Created with IntelliJ IDEA.
 * User: 1
 * Date: 12.08.12
 * Time: 23:07
 * To change this template use File | Settings | File Templates.
 */
public class Rational implements Comparable<Rational> {
    private long numerator;
    private long denominator;
    public static Rational ZERO = new Rational(0, 1);
    public static Rational ONE = new Rational(1, 1);

    public Rational(String s) {
        String[] spl = s.split("[/ ]");
        if (spl.length > 2)
            throw new IllegalArgumentException();
        Rational tmp;
        if (spl.length == 1)
            tmp = new Rational(Long.parseLong(spl[0]));
        else
            tmp = new Rational(Long.parseLong(spl[0]), Long.parseLong(spl[1]));
        this.numerator = tmp.getNumerator();
        this.denominator = tmp.getDenominator();
    }

    public Rational(long a, long b) {
        if (b == 0)
            throw new ArithmeticException("division by zero");
        long g = MathUtils.gcd(a, b);
        if (g > 1) {
            a /= g;
            b /= g;
        }
        if (b < 0) {
            a = -a;
            b = -b;
        }
        numerator = a;
        denominator = b;
    }

    public Rational(long a) {
        this(a, 1);
    }

    public Rational add(Rational other) {
        long lcm = MathUtils.lcm(denominator, other.denominator);
        return new Rational(lcm / denominator * numerator + lcm / other.denominator * other.numerator, lcm);
    }

    public long getNumerator() {
        return numerator;
    }

    public void setNumerator(long numerator) {
        this.numerator = numerator;
    }

    public long getDenominator() {
        return denominator;
    }

    public void setDenominator(long denominator) {
        this.denominator = denominator;
    }

    public Rational subtract(Rational other) {
        long lcm = MathUtils.lcm(denominator, other.denominator);
        return new Rational(lcm / denominator * numerator - lcm / other.denominator * other.numerator);
    }

    public Rational multiply(Rational other) {
        return new Rational(numerator * other.numerator, denominator * other.denominator);
    }

    public Rational divide(Rational other) {
        return new Rational(numerator * other.denominator, denominator * other.numerator);
    }

    public Rational negate(Rational other) {
        return new Rational(-numerator, -denominator);
    }

    @Override
    public int compareTo(Rational o) {
        return Long.signum(numerator * o.denominator - o.numerator * denominator);
    }

    @Override
    public String toString() {
        return numerator + "/" + denominator;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Rational rational = (Rational) o;

        if (denominator != rational.denominator) return false;
        if (numerator != rational.numerator) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = (int) (numerator ^ (numerator >>> 32));
        result = 31 * result + (int) (denominator ^ (denominator >>> 32));
        return result;
    }
}
